'''
UNIT INFO (module)
- Class with dynamically generated controls based on a definition-variable
(like testdefdi)
- also callable from an aui-framework

BACKGROUND INFO
- args can be called as kwargs if there are no positional conflicts

ADAP HIS
- added a style-parameter to the defdi for textctrls
- updated size-handling
-add all implemented controls to testdictionary
-generalize extensibility of definition dict with resp. to styles
-make memo-field multi-lined
-implement the listbox
-usage with a dialog-window

ADAP NO


ADAP FUT
-built in enabling and clearing etc for a paramterized control-list
-investigate crash if started without reinitializing

DEBUGGING
- test debug-tools
    - look at the manuals
- bugs:
'''

import wx
import jotools

# system-settings-db parameter to adjust the size of the font (point-size)
pointcorrectionit = 0

# definitie vd control: key/naam, en dan: wx controltype, label, position, size, index en
#   event-lijst en soms de stijl
testdefdi =           {
            "labSource":["StaticText","Source",(10,5),(),0,["SET_FOCUS"]],
            "txtSource":["TextCtrl","",(300,50),(100,80),1,["TEXT"],["TE_MULTILINE"]],
            "labSubject":["StaticText","Subject",(160,5),(),2,["SET_FOCUS"]],
            "txtSubject":["TextCtrl","",(220,5),(100,21),3,["TEXT","TEXT_ENTER"],["TE_PROCESS_ENTER"]],
            "knopDruk":["Button","Drukken",(150,100),(),4,["BUTTON"]],
            "textHai":["TextCtrl","Hai",(30,50),(),5,["TEXT"]],
            "labelLab":["StaticText","labeltje",(250,50),(),6,["SET_FOCUS"]],
            "knopMega":["Button","Mega",(50,100),(),7,["BUTTON"]],
            "chkHide":["CheckBox","Hide completed",(10,35),(),8,["CHECKBOX"]],
            "cboSource":["ComboBox","",(10,130),(110,21),9,["COMBOBOX"],['CB_READONLY']],
            "lstBox":["ListBox","",(10,160),(110,70),10,["LISTBOX"]]
             }

##            "txtSubject":["TextCtrl","",(220,5),(100,21),3,["TEXT","TEXT_ENTER"],["TE_PROCESS_ENTER"]],
##            "txtSource":["TextCtrl","",(300,50),(100,80),1,["TEXT"],["TE_MULTILINE"]],
##            "cboSource":["ComboBox","",(10,130),(110,21),9,["COMBOBOX","TEXT_ENTER"],["TE_PROCESS_ENTER"]],


##testdefdiBackup =           {
##            "labSource":["StaticText","Source",(10,5),(),0,["SET_FOCUS"]],
##            "txtSource":["TextCtrl","",(50,5),(),1,["TEXT"]],
##            "labSubject":["StaticText","Subject",(160,5),(),2,["SET_FOCUS"]],
##            "txtSubject":["TextCtrl","",(220,5),(300,21),3,["TEXT"]],
##            "knopDruk":["Button","Drukken",(150,100),(),4,["BUTTON"]],
##            "textHai":["TextCtrl","Hai",(30,50),(),5,["TEXT"]],
##            "labelLab":["StaticText","labeltje",(250,50),(),6,["SET_FOCUS"]],
##            "knopMega":["Button","Mega",(50,100),(),7,["BUTTON"]]
##             }

def actualSize(size):
    if size ==():
        return wx.DefaultSize
    else:
        return size


def actualStyle(listli):
    # take default if element misses
    lenit = len(listli)
##    print lenit
    if lenit < 7:
        return 0    # default style
    else:
##        print listli[6]
        stylit = totalizeConstants(listli[6])
        return stylit


def totalizeConstants(constantli):
    # convert text-based styles-list to an aggregated number
    sumConstantit = 0
    for constantst in constantli:
        print sumConstantit
        sumConstantit = sumConstantit + getattr(wx,constantst)
##    sumConstantit = long(sumConstantit)
    print sumConstantit
    print type(sumConstantit)
    return sumConstantit

class genPanel1(wx.Panel):
    '''
    UNIT INFO -
    Controls are generated here on basis of the gui definition
    '''

    def __init__(self, parent, ID, pos = wx.DefaultPosition,
            size = wx.DefaultSize, controlsDefDict = None ):
        wx.Panel.__init__(self, parent,ID, pos, size)

        # create a dictionary with the available events of wx
        self.eventDict = {}
        eventli = [e for e in dir(wx) if e[:4]=='EVT_']
        for e in eventli:
            if hasattr (getattr(wx,e),'typeId'):
                x = e[4:len(e)]
                y =getattr(wx,e).typeId
                self.eventDict[x] = y
##            print x + " - " + str(y)

        # create local definition dictionary and  derive a list from it
        self.defdi = controlsDefDict    # see testdefdi above

##        defli = self.defdi.items()  # old unsorted list
        # like defdi.items() but sorted
        defli = jotools.buildSortedItemsList(self.defdi,4)
        print defli
        # create a control-dict
        self.ctrldi = {}

        #---adjust default font-point-size relatively
        if pointcorrectionit <> 0:
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            curpointsize = font.GetPointSize()
            print curpointsize
            font.SetPointSize(curpointsize + pointcorrectionit)
        #------------------------------------------

        # for every controldef in list do instantiate control and bind the events
        # tedo: check event ID's voor meervoudige events
        for cdeftu in defli:
            it = defli.index(cdeftu)     # ID (=it) is nodig voor identificatie
            if cdeftu[1][0] in ['TextCtrl','ComboBox']:
                stylit = actualStyle(cdeftu[1])
                self.ctrldi[cdeftu[0]]=getattr(wx,cdeftu[1][0])(self, cdeftu[1][4],
                    cdeftu[1][1], cdeftu[1][2], actualSize(cdeftu[1][3]),
                    style = stylit,name=cdeftu[0])
            elif cdeftu[1][0] == 'ListBox':  # label is not present in listbox
                self.ctrldi[cdeftu[0]]=getattr(wx,cdeftu[1][0])(self, cdeftu[1][4],
                    cdeftu[1][2], actualSize(cdeftu[1][3]),
                    style = actualStyle(cdeftu[1]),name=cdeftu[0])
            else:
                self.ctrldi[cdeftu[0]]=getattr(wx,cdeftu[1][0])(self, cdeftu[1][4],
                    cdeftu[1][1], cdeftu[1][2], actualSize(cdeftu[1][3]),
                    name=cdeftu[0])

##            print actualStyle(cdeftu[1])
            # binding events
            for eventst in cdeftu[1][5]:
                fullEvst = 'EVT_' + eventst
                self.Bind(getattr(wx, fullEvst), getattr(self, "onAnyEvent"),
                    id = cdeftu[1][4])
##                self.Bind(getattr(wx, fullEvst), getattr(self, "onAnyEvent"),
##                    self.ctrldi[cdeftu[0]])

            if pointcorrectionit <> 0: self.ctrldi[cdeftu[0]].SetFont(font)


            # temporary sizing values
            pName = str(self.ctrldi[cdeftu[0]].Name)
            pPos = str(self.ctrldi[cdeftu[0]].Position)
            pSize = str(self.ctrldi[cdeftu[0]].Size)
            print pName + '\n' + ' - ' + pPos + ', ' + pSize
##            print pName


    def evtTypeIs(self, eTypeit, eventNamest):
        if eTypeit == self.eventDict[eventNamest]:
            return True

    def ctrlNameIs(self, eIDit, controlNamest):
        if eIDit == self.defdi[controlNamest][4]:
            return True

    def onAnyEvent(self, evt):
        t = evt.GetEventType()
        c = evt.GetId()

        if self.evtTypeIs(t,'BUTTON'):
            if self.ctrlNameIs(c,'knopMega'):
                newst = self.ctrldi["textHai"].Value
                self.ctrldi["labelLab"].SetLabel(newst)
            elif self.ctrlNameIs(c,'knopDruk'):
                msg = wx.MessageDialog(
                    self,"Hee daar...Hoest?","Bericht",wx.OK | wx.ICON_QUESTION)
                     # wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION
                msg.ShowModal()
                msg.Destroy()
        elif self.evtTypeIs(t,'TEXT'):
            if self.ctrlNameIs(c,'txtSource'):
                print 'typen'
        elif self.evtTypeIs(t,'TEXT_COPY'):
            if self.ctrlNameIs(c,'txtSource'):
                print 'copy'
        elif self.evtTypeIs(t,'TEXT_ENTER'):
            if self.ctrlNameIs(c,'txtSource'):
                print 'enter'
##            if self.ctrlNameIs(c,'cboSource'):
##                print 'combo enter'
##                msg = wx.MessageDialog(
##                    self,"combo enter","Bericht",wx.OK | wx.ICON_QUESTION)
##                     # wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION
##                msg.ShowModal()
##                msg.Destroy()

        elif self.evtTypeIs(t,'LISTBOX'):
            if self.ctrlNameIs(c,'lstBox'):
                print 'listbox'
        elif self.evtTypeIs(t,'CHECKBOX'):
            if self.ctrlNameIs(c,'chkHide'):
                print 'hoi'


    def enableControlList(self, controlli, enablebo):
        for controlst in controlli:
            self.ctrldi[controlst].Enable(enablebo)

    def showControlList(self, controlli, showbo):
        for controlst in controlli:
            self.ctrldi[controlst].Show(showbo)

    def validateControlList(self, controlli, validationtypest, excludedtokensli=[]):
        nofaultyet = True
        for controlst in controlli:
            if validationtypest == 'filled-in':
                if len(self.ctrldi[controlst].Value) == 0:
                    nofaultyet = False
                    break
            if validationtypest == 'no-forbidden-tokens':
                for tokenst in excludedtokensli:
                    if tokenst in self.ctrldi[controlst].Value:
                        nofaultyet = False
                        break
        return nofaultyet


class specPanel(genPanel1):
    def __init__(self, parent, ID, pos = wx.DefaultPosition,
            size = wx.DefaultSize, controlsDefDict = None ):
        genPanel1.__init__(self, parent,ID, pos, size, controlsDefDict)

##        listli = ['a','b','c']
##        self.ctrldi['lstBox'].InsertItems(listli,0)


##    def onAnyEvent(self, evt):
##        t = evt.GetEventType()
##        c = evt.GetId()
##
##        if self.evtTypeIs(t,'BUTTON'):
##            if self.ctrlNameIs(c,'knopMega'):
##                newst = self.ctrldi["textHai"].Value + ' Joris'
##                self.ctrldi["labelLab"].SetLabel(newst)
##            elif self.ctrlNameIs(c,'knopDruk'):
##                msg = wx.MessageDialog(
##                    self,"Hee daar...Gaat t nog een beetje?","Bericht",wx.OK | wx.ICON_QUESTION)
##                     # wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION
##                msg.ShowModal()
##                msg.Destroy()
##
##        elif self.evtTypeIs(t,'TEXT'):
##            pass
##        elif self.evtTypeIs(t,'TEXT_COPY'):
##            pass

class genFrame(wx.Frame):
    def __init__(self, parent, ID, title, pos=wx.DefaultPosition,
            size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE):
        wx.Frame.__init__(self, parent, ID, title, pos, size, style)
##        p = genPanel1(self, ID,controlsDefList = testdefli2 )
        p = specPanel(self, -1, controlsDefDict = testdefdi )


class testDialog(wx.Dialog):
    def __init__ (self, parent, ID, title="Dialog-test", pos=wx.DefaultPosition,
            size=wx.DefaultSize, style = wx.DEFAULT_DIALOG_STYLE):
        wx.Dialog.__init__(self, parent, ID, title, pos, size, style)

        pan = specPanel(self, -1, controlsDefDict = testdefdi )

        # wx.dialog does not autosize panels aot frames
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(pan, 1, wx.EXPAND|wx.ALL, 5)
        self.SetSizer(sizer)
##        sizer.Fit(self)     # shrink dialog-size to minimal


class myApp(wx.App):
    def OnInit(self):
        useDialogbo = True
        if not useDialogbo:
            frame= genFrame(None, -1, "Frame with dynamic controls", size=(500, 300))
            frame.Show(1)
            self.SetTopWindow(frame)
        else:
            dlg = testDialog(None, -1, "Sample Dialog", size=(500, 300))
    ##                         #style=wx.CAPTION | wx.SYSTEM_MENU | wx.THICK_FRAME,
    ##                         style=wx.DEFAULT_DIALOG_STYLE) # & ~wx.CLOSE_BOX,

            dlg.CenterOnScreen()

            # this does not return until the dialog is closed.
            val = dlg.ShowModal()
            dlg.Destroy()
            self.SetTopWindow(dlg)
        return True


if __name__ == '__main__':
    app = myApp(0)
    app.MainLoop()



